using System.Data;
using System.Reflection;
using NUnit.Framework;

namespace Spring.Transaction.Interceptor;

[TestFixture]
public class TransactionAttributeSourceEditorTests
{
    [Test]
    public void Null()
    {
        TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
        pe.SetAsText(null);
        ITransactionAttributeSource tas = pe.Value;
        MethodInfo m = typeof(object).GetMethod("GetHashCode");
        Assert.IsTrue(tas.ReturnTransactionAttribute(m, null) == null);
    }

    [Test]
    public void Invalid()
    {
        TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
        Assert.Throws<ArgumentException>(() => pe.SetAsText("foo=bar"));
    }

    [Test]
    public void MatchesSpecific()
    {
        TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
        pe.SetAsText("System.Object.GetHashCode, Mscorlib =PROPAGATION_REQUIRED\n" +
                     "System.Object.Equals, Mscorlib =PROPAGATION_MANDATORY\n" +
                     "System.Object.*pe, Mscorlib=PROPAGATION_SUPPORTS");
        ITransactionAttributeSource tas = pe.Value;

        checkTransactionProperties(tas, typeof(object).GetMethod("GetHashCode"), TransactionPropagation.Required);
        checkTransactionProperties(tas, typeof(object).GetMethod("Equals", new Type[] { typeof(object) }), TransactionPropagation.Mandatory);
        checkTransactionProperties(tas, typeof(object).GetMethod("GetType"), TransactionPropagation.Supports);
        checkTransactionProperties(tas, typeof(object).GetMethod("ToString"));
    }

    [Test]
    public void MatchesAll()
    {
        TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
        pe.SetAsText("System.Object.*, Mscorlib=PROPAGATION_REQUIRED");
        ITransactionAttributeSource tas = pe.Value;

        checkTransactionProperties(tas, typeof(object).GetMethod("GetHashCode"), TransactionPropagation.Required);
        checkTransactionProperties(tas, typeof(object).GetMethod("Equals", new Type[] { typeof(object) }), TransactionPropagation.Required);
        checkTransactionProperties(tas, typeof(object).GetMethod("GetType"), TransactionPropagation.Required);
        checkTransactionProperties(tas, typeof(object).GetMethod("ToString"), TransactionPropagation.Required);
    }

    private void checkTransactionProperties(ITransactionAttributeSource tas, MethodInfo method)
    {
        ITransactionAttribute ta = tas.ReturnTransactionAttribute(method, null);
        Assert.IsNull(ta);
    }

    private void checkTransactionProperties(ITransactionAttributeSource tas, MethodInfo method, TransactionPropagation transactionPropagation)
    {
        ITransactionAttribute ta = tas.ReturnTransactionAttribute(method, null);
        Assert.IsTrue(ta != null);
        Assert.IsTrue(ta.TransactionIsolationLevel == IsolationLevel.ReadCommitted);
        Assert.IsTrue(ta.PropagationBehavior == transactionPropagation);
    }
}